#ifndef _DEV_MPU9250_H_
#define _DEV_MPU9250_H_

#include "data_type.h"

/******************************************* 寄存器列表 *******************************************/
/* REG(W) */
#define DEV_MPU9250_SMPLRT_DIV_REG             0X19  /* 采样频率分频器 */
#define DEV_MPU9250_GYRO_CONFIG_REG            0X1B  /* 陀螺仪配置寄存器 */
#define DEV_MPU9250_CONFIG_REG                 0X1A  /* 配置寄存器 */
#define DEV_MPU9250_ACCEL_CONFIG_REG           0X1C  /* 加速度计寄存器 */
#define DEV_MPU9250_FIFO_EN_REG                0X23  /* FIFO配置寄存器 */
#define DEV_MPU9250_I2CMST_CTRL_REG            0x24  /* IIC主机控制寄存器 */
#define DEV_MPU9250_I2CSLV0_ADDR_REG           0x25  /* IIC从机0器件地址寄存器 */
#define DEV_MPU9250_I2CSLV0_REG                0x26  /* IIC从机0数据地址寄存器 */
#define DEV_MPU9250_I2CSLV0_CTRL_REG           0x27  /* IIC从机0控制寄存器 */
#define DEV_MPU9250_I2CSLV1_ADDR_REG           0x28  /* IIC从机1器件地址寄存器 */
#define DEV_MPU9250_I2CSLV1_REG                0x29  /* IIC从机1数据地址寄存器 */
#define DEV_MPU9250_I2CSLV1_CTRL_REG           0x2A  /* IIC从机1控制寄存器 */
#define DEV_MPU9250_I2CSLV2_ADDR_REG           0x2B  /* IIC从机2器件地址寄存器 */
#define DEV_MPU9250_I2CSLV2_REG                0x2C  /* IIC从机2数据地址寄存器 */
#define DEV_MPU9250_I2CSLV2_CTRL_REG           0x2D  /* IIC从机2控制寄存器 */
#define DEV_MPU9250_I2CSLV3_ADDR_REG           0x2E  /* IIC从机3器件地址寄存器 */
#define DEV_MPU9250_I2CSLV3_REG                0x2F  /* IIC从机3数据地址寄存器 */
#define DEV_MPU9250_I2CSLV3_CTRL_REG           0x30  /* IIC从机3控制寄存器 */
#define DEV_MPU9250_I2CSLV4_ADDR_REG           0x31  /* IIC从机4器件地址寄存器 */
#define DEV_MPU9250_I2CSLV4_REG                0x32  /* IIC从机4数据地址寄存器 */
#define DEV_MPU9250_I2CSLV4_DO_REG             0x33  /* IIC从机4写数据寄存器 */
#define DEV_MPU9250_I2CSLV4_CTRL_REG           0x34  /* IIC从机4控制寄存器 */
#define DEV_MPU9250_I2CSLV4_DI_REG             0x35  /* IIC从机4读数据寄存器 */
#define DEV_MPU9250_I2CMST_STA_REG             0x36  /* IIC主机状态寄存器 */
#define DEV_MPU9250_INTBP_CFG_REG              0x37  /* 中断/旁路设置寄存器 */
#define DEV_MPU9250_INT_EN_REG                 0x38  /* 中断使能寄存器 */
#define DEV_MPU9250_INT_STA_REG                0x3A  /* 中断状态寄存器 */

/* REG(R) */
#define DEV_MPU9250_ACCEL_XOUT_H_REG           0x3B  /* 加速度计X轴数据高8位 */
#define DEV_MPU9250_ACCEL_XOUT_L_REG           0x3C  /* 加速度计X轴数据低8位 */
#define DEV_MPU9250_ACCEL_YOUT_H_REG           0x3D  /* 加速度计Y轴数据高8位 */
#define DEV_MPU9250_ACCEL_YOUT_L_REG           0x3E  /* 加速度计Y轴数据低8位 */
#define DEV_MPU9250_ACCEL_ZOUT_H_REG           0x3F  /* 加速度计Z轴数据高8位 */
#define DEV_MPU9250_ACCEL_ZOUT_L_REG           0x40  /* 加速度计Z轴数据低8位 */
#define DEV_MPU9250_TEMP_OUT_H_REG             0x41  /* 温度计数据高8位 */
#define DEV_MPU9250_TEMP_OUT_L_REG             0x42  /* 温度计数据低8位 */
#define DEV_MPU9250_GYRO_XOUT_H_REG            0x43  /* 陀螺仪X轴数据高8位 */
#define DEV_MPU9250_GYRO_XOUT_L_REG            0x44  /* 陀螺仪X轴数据低8位 */
#define DEV_MPU9250_GYRO_YOUT_H_REG            0x45  /* 陀螺仪Y轴数据高8位 */
#define DEV_MPU9250_GYRO_YOUT_L_REG            0x46  /* 陀螺仪Y轴数据低8位 */
#define DEV_MPU9250_GYRO_ZOUT_H_REG            0x47  /* 陀螺仪Z轴数据高8位 */
#define DEV_MPU9250_GYRO_ZOUT_L_REG            0x48  /* 陀螺仪Z轴数据低8位 */

#define DEV_MPU9250_I2CSLV0_DO_REG             0x63    /* IIC从机0数据寄存器 */
#define DEV_MPU9250_I2CSLV1_DO_REG             0x64    /* IIC从机1数据寄存器 */
#define DEV_MPU9250_I2CSLV2_DO_REG             0x65    /* IIC从机2数据寄存器 */
#define DEV_MPU9250_I2CSLV3_DO_REG             0x66    /* IIC从机3数据寄存器 */
 
#define DEV_MPU9250_I2CMST_DELAY_REG           0x67    /* IIC主机延时管理寄存器 */
#define DEV_MPU9250_SIGPATH_RST_REG            0x68    /* 信号通道复位寄存器 */
#define DEV_MPU9250_MDETECT_CTRL_REG           0x69    /* 运动检测控制寄存器 */
#define DEV_MPU9250_USER_CTRL_REG              0x6A    /* 用户控制寄存器 */
#define DEV_MPU9250_PWR_MGMT1_REG              0x6B    /* 电源管理寄存器1 */
#define DEV_MPU9250_PWR_MGMT2_REG              0x6C    /* 电源管理寄存器2 */
#define DEV_MPU9250_FIFO_CNTH_REG              0x72    /* FIFO计数寄存器高八位 */
#define DEV_MPU9250_FIFO_CNTL_REG              0x73    /* FIFO计数寄存器低八位 */
#define DEV_MPU9250_FIFO_RW_REG                0x74    /* FIFO读写寄存器 */
#define DEV_MPU9250_WHO_AM_I_REG               0x75    /* ID识别寄存器 */

/* 寄存器固定值 */ 
#define DEV_MPU9250_IMU_ID                     0x71    /* IMU的器件ID */

/* AK8963的内部寄存器 */
#define DEV_MPU9250_MAG_WIA_REG                0x00    /* AK8963的器件ID寄存器地址 */
#define DEV_MPU9250_MAG_ST1_REG                0x02    /* Data status */
#define DEV_MPU9250_MAG_XOUT_L_REG             0X03    /* X-axis data */
#define DEV_MPU9250_MAG_XOUT_H_REG             0X04
#define DEV_MPU9250_MAG_YOUT_L_REG             0X05    /* Y-axis data */
#define DEV_MPU9250_MAG_YOUT_H_REG             0X06
#define DEV_MPU9250_MAG_ZOUT_L_REG             0X07    /* Z-axis data */
#define DEV_MPU9250_MAG_ZOUT_H_REG             0X08
#define DEV_MPU9250_MAG_CNTL1_REG              0X0A    /* 控制寄存器1 (数据位数, 工作模式) */
#define DEV_MPU9250_MAG_CNTL2_REG              0X0B    /* 控制寄存器2 (软件复位) */
#define DEV_MPU9250_MAG_ASAX                   0X10    /* Magnetic sensor X-axis sensitivity adjustment value */
#define DEV_MPU9250_MAG_ASAY                   0X11    /* Magnetic sensor Y-axis sensitivity adjustment value */
#define DEV_MPU9250_MAG_ASAZ                   0X12    /* Magnetic sensor Z-axis sensitivity adjustment value */

/* MAG工作模式配置 */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_PD        0x00     /* Power-down mode */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_SM        0x01     /* Single measurement mode */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_CM1       0x02     /* Continuous measurement mode 1 */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_CM2       0x06     /* Continuous measurement mode 2 */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_ETM       0x04     /* External trigger measurement mode */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_ST        0x08     /* Self-test mode */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_FRA       0x0F     /* Fuse ROM access mode */
#define DEV_MPU9250_MAG_CMD_CTRL1_WM_FRA       0x0F     /* Fuse ROM access mode */

/* MAG输出位数 */
#define DEV_MPU9250_MAG_CMD_CTRL1_BIT_14       (0 << 4) /* 14-bit output */
#define DEV_MPU9250_MAG_CMD_CTRL1_BIT_16       (1 << 4) /* 16-bit output */

/* MAG软件复位 */
#define DEV_MPU9250_MAG_CMD_CTRL2_SR           0x1     /* Reset */
 
/* 寄存器固定值 */ 
#define DEV_MPU9250_MAG_ID                     0x48    /* MAG的器件ID */

/* user macro */
/* 等待重启时间(MS) */
#define DEV_MPU9250_WAIT_RESTART_TIME_MS       100
#define DEV_MPU9250_REG_NOB                    1       /* 每个寄存器的字节数 (number of bytes) */

/* IMU采样频率: Hz */
#define DEV_MPU9250_IMU_SAMPLE_RATE            50

/* ACC & GYRO 量程 */
#define DEV_MPU9250_IMU_ACC_RANGE_2G           (0x00 << 3)
#define DEV_MPU9250_IMU_ACC_RANGE_4G           (0x01 << 3)
#define DEV_MPU9250_IMU_ACC_RANGE_8G           (0x10 << 3)
#define DEV_MPU9250_IMU_ACC_RANGE_16G          (0x11 << 3)
#define DEV_MPU9250_IMU_ACC_RANGE_SET          DEV_MPU9250_IMU_ACC_RANGE_2G

#define DEV_MPU9250_IMU_GYRO_RANGE_250DPS      (0x00 << 3)
#define DEV_MPU9250_IMU_GYRO_RANGE_500DPS      (0x01 << 3)
#define DEV_MPU9250_IMU_GYRO_RANGE_1000DPS     (0x10 << 3)
#define DEV_MPU9250_IMU_GYRO_RANGE_2000DPS     (0x11 << 3)
#define DEV_MPU9250_IMU_GYRO_RANGE_SET         DEV_MPU9250_IMU_GYRO_RANGE_2000DPS

/* MAG工作模式和输出数据位数配置 */
#define DEV_MPU9250_MAG_WORKMODE_SET           DEV_MPU9250_MAG_CMD_CTRL1_WM_SM
#define DEV_MPU9250_MAG_DATA_BIT_SET           DEV_MPU9250_MAG_CMD_CTRL1_BIT_16

/************************************** 其它宏定义(配置相关, 必读) *************************************/

/* 从机目标 */
enum
{
    DEV_MPU9250_TARGET_IMU = 0, /* IMU */
    DEV_MPU9250_TARGET_MAG,     /* MAG */
};

/* 获得的数据类型 */
enum
{
    DEV_MPU9250_DATA_ACC = 0,   /* 加速度数据 */
    DEV_MPU9250_DATA_GYRO,      /* 陀螺仪数据 */
    DEV_MPU9250_DATA_MAG,       /* 电子罗盘数据 */
    DEV_MPU9250_DATA_TEMP,      /* 温度数据 */
};

/* AHRS设备数据 */
typedef struct DEV_MPU9250_AXIS
{
    dt_3axis_s2 acc;
    dt_3axis_s2 gyro;
    dt_3axis_s2 mag;
} dev_mpu9250_axis;

/* 设备驱动管理结构体 */
typedef struct DEV_RTDRV_MPU9250
{
    INIT_STATUS              init_status;                       /* 设备初始化状态 */
    uint8_t                  imu_addr;                          /* 从机地址 */
    uint8_t                  mag_addr;                          /* 从机地址 */
    struct rt_i2c_bus_device *i2c_bus;                          /* I2C总线设备句柄 */
    dev_mpu9250_axis         axis_data;                         /* 传感器数据 */
    float                    temp_data;                         /* 温度数据 */
    float                    yaw_data;                          /* YAW角 */
} dev_rtdrv_mpu9250;
typedef dev_rtdrv_mpu9250 *dev_rtdrv_mpu9250_t;

/* MPU9250设备初始化 */
RET_STATUS dev_mpu9250_init(void);
/* 获得MPU9250数据 */
RET_STATUS dev_mpu9250_get_data(uint8_t data_type, void *buf);
/* 测试MPU9250罗盘 */
RET_STATUS dev_mpu9250_test_yaw(float *yaw_angle);

#endif
